import java.util.*;
public class Solution {
    //JZ29 顺时针打印矩阵
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        ArrayList<Integer> array = new ArrayList<>();
        //先排除为空的情况
        if(matrix.length == 0){
            return array;
        }
        //模拟边界
        //行列长度
        int line = matrix[0].length;
        int row = matrix.length;
        //左边界
        int left = 0;
        //右边界
        int right = line - 1;
        //上边界
        int up = 0;
        //下边界
        int down = row - 1;
        while(left <= right && up <= down){
            //先将上边界从左往右放入
            for(int i = left; i <= right; i++){
                //上边界来作为当前行
                array.add(matrix[up][i]);
            }
            //控制大小
            if(line * row == array.size()){
                break;
            }
            //将右边界值由上到下放入(上边界第一层放过了，跳过即可)
            for(int i = up + 1; i <= down; i++){
                //右边界来作为当前列
                array.add(matrix[i][right]);
            }

            //将下边界从右往左放入(有边界第一列放过，跳过即可)
            for(int i = right - 1; i >= left; i--){
                //下边界来作为当前行
                array.add(matrix[down][i]);
            }
            //控制大小
            if(line * row == array.size()){
                break;
            }
            //将左边界从下往上放入(下边界放过，跳过即可，注意:顶部已经放过，不变再放)
            for(int i = down - 1; i > up; i--){
                //左边界作为当前列
                array.add(matrix[i][left]);
            }
            //调整边界
            up++;
            right--;
            down--;
            left++;
        }
        return array;
    }
    //JZ61 扑克牌顺子
    public boolean IsContinuous(int [] numbers) {
        //分析，最大值-最小值 < 5
        //0在最后求和的时候可以代替一个数
        Set<Integer> set = new HashSet<>();
        //统计0的个数
        int count = 0;
        //最大值和最小值
        int max = numbers[0];
        int min = 14;
        int len = numbers.length;
        //遍历统计
        for(int i = 0; i < len; i++){
            //统计0的个数
            if(numbers[i] == 0){
                count++;
            }
            //统计最大值最小值
            if(numbers[i] > max){
                max = numbers[i];
            }
            if(numbers[i] != 0 && numbers[i] < min){
                min = numbers[i];
            }
            //放入set中
            if(!set.contains(numbers[i])){
                if(numbers[i] != 0){
                    set.add(numbers[i]);
                }
            }else{
                //一旦有重复就不可能是顺子
                return false;
            }
        }
        if((max - min < 5) && (set.size() + count == 5)){
            return true;
        }else{
            return false;
        }
    }
    //JZ61 扑克牌顺子(可以不用统计0的个数,直接用max - min < 5判断即可)
/*    public boolean IsContinuous(int [] numbers) {
        //分析，最大值-最小值 < 5
        //0在最后求和的时候可以代替一个数
        Set<Integer> set = new HashSet<>();
        //最大值和最小值
        int max = numbers[0];
        int min = 14;
        int len = numbers.length;
        //遍历统计
        for(int i = 0; i < len; i++){
            //统计最大值最小值
            if(numbers[i] > max){
                max = numbers[i];
            }
            if(numbers[i] != 0 && numbers[i] < min){
                min = numbers[i];
            }
            //放入set中
            if(!set.contains(numbers[i])){
                if(numbers[i] != 0){
                    set.add(numbers[i]);
                }
            }else{
                //一旦有重复就不可能是顺子
                return false;
            }
        }
        if(max - min < 5){
            return true;
        }else{
            return false;
        }
    }*/
    //JZ67 把字符串转换成整数(atoi)
    public int StrToInt (String s) {
        // write code here
        //判断是否无效
        if (s == null)
            return 0;
        //切割首尾空格
        s = s.trim();
        if (s.equals(""))
            return 0;
        char first = s.charAt(0);
        int res = 0;
        //判断头部是否有效
        if (!(first == '-' || first == '+' || (first >= '0' && first <= '9')))
            return 0;
        //记录数字开始的有效位置
        int start = 0;
        //用于判断是否超出32位有效整数
        int minq = Integer.MIN_VALUE / 10;
        int minr = Integer.MIN_VALUE % 10;
        //判断结果正负
        boolean pos = first == '-' ? false : true;
        if (first == '-' || first == '+')
            start++;
        //一律用负数表示结果，最后再定正负
        for (int i = start; i < s.length(); i++) {
            char cur = s.charAt(i);
            //若当前字符无效，立刻停止
            if (cur < '0' || cur > '9')
                break;
            //计算当前字符表示的数字
            int val = 0 - Integer.parseInt(Character.toString(cur));
            //如果超出了最小负整数
            if (res < minq || (res == minq && val < minr))
                return pos ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            res = res * 10 + val;
        }
        //根据正负号，返回对应的值
        return pos ? res == Integer.MIN_VALUE ? Integer.MAX_VALUE : - res : res;
    }
}
